// 微信小程序主入口文件
const appConfig = require('./config/app.js')
const WebSocketManager = require('./utils/WebSocketManager.js')

App({
  globalData: {
    userInfo: null,
    currentRoom: null,
    websocket: null,
    baseUrl: appConfig.server.baseUrl,
    isLoggedIn: false
  },

  onLaunch(options) {
    console.log('打牌记账小程序启动', options)
    this.initGlobalErrorHandler()
    // 检查网络配置
    this.checkNetworkConfiguration()
    
    // 处理启动场景
    this.handleLaunchScene(options)
    
    // 先检查登录状态，只有登录后才初始化WebSocket
    this.checkLoginStatusAndInitWebSocket()
  },

  // 处理小程序启动场景
  handleLaunchScene(options) {
    console.log('启动场景参数:', options)
    
    // 处理通过分享链接或扫码进入的场景
    if (options.query) {
      const query = options.query
      
      // 如果是通过房间链接进入
      if (query.roomCode) {
        console.log('通过房间链接进入，房间代码:', query.roomCode)
        wx.setStorageSync('pending_room_code', query.roomCode)
      }
      
      // 如果是通过用户分享进入
      if (query.from_user_id) {
        console.log('通过用户分享进入，邀请者ID:', query.from_user_id)
        wx.setStorageSync('inviter_user_id', query.from_user_id)
      }
    }
    
    // 处理扫码进入的场景
    if (options.scene === 1047 || options.scene === 1048 || options.scene === 1049) {
      console.log('通过扫码进入，场景值:', options.scene)
      if (options.query && options.query.roomCode) {
        wx.setStorageSync('pending_room_code', options.query.roomCode)
      }
    }
  },

  // 小程序显示（从后台进入前台）
  onShow(options) {
    console.log('小程序显示（从后台恢复）', options)
    
    // 检查登录状态
    this.checkLoginStatus()
    
    // 如果已登录，检查并重连 WebSocket（如果需要）
    if (this.globalData.isLoggedIn && this.globalData.userInfo) {
      const manager = this.getWebSocketManager()
      
      // 如果连接断开，自动重连
      if (!manager.isConnected()) {
        console.log('检测到 WebSocket 连接断开，开始重连...')
        this.reconnectWebSocket()
      } else {
        console.log('WebSocket 连接正常，无需重连')
      }
    }
    
    // 处理恢复场景（如果有房间代码）
    if (options.query && options.query.roomCode) {
      console.log('onShow: 检测到房间代码，保存到待处理:', options.query.roomCode)
      wx.setStorageSync('pending_room_code', options.query.roomCode)
      // 如果用户在房间页面，应该直接跳转到该房间
      const pages = getCurrentPages()
      const currentPage = pages[pages.length - 1]
      if (currentPage && currentPage.route === 'pages/room/room') {
        // 如果当前在房间页面，直接设置roomCode并加载房间信息
        console.log('当前在房间页面，直接加载房间信息')
        if (currentPage.setData && typeof currentPage.setData === 'function') {
          currentPage.setData({ roomCode: options.query.roomCode }, () => {
            if (currentPage.getRoomInfo && typeof currentPage.getRoomInfo === 'function') {
              currentPage.getRoomInfo()
            }
            if (currentPage.getRoomRecords && typeof currentPage.getRoomRecords === 'function') {
              currentPage.getRoomRecords(1, false)
            }
          })
          // 清除待处理的房间代码
          wx.removeStorageSync('pending_room_code')
        }
      }
    }
  },

  // 重连 WebSocket（简化版，只负责重连，后端会自动订阅）
  async reconnectWebSocket() {
    const manager = this.getWebSocketManager()
    
    try {
      console.log('开始重连 WebSocket...')
      
      // 如果正在重连中，避免重复重连
      if (manager.reconnectAttempts > 0 && manager.reconnectAttempts < manager.maxReconnectAttempts) {
        console.log('WebSocket 正在重连中，跳过重复请求')
        return
      }
      
      // 重置重连计数，允许重新尝试
      manager.reconnectAttempts = 0
      
      // 等待连接建立（连接成功后会自动发送 connect 消息，后端会自动订阅）
      await manager.ensureConnection()
      console.log('WebSocket 重连成功，后端会自动订阅房间')
      
      // 注册消息处理器（后端已自动订阅）
      await this.registerRoomMessageHandlers()
      
    } catch (error) {
      console.error('WebSocket 重连失败:', error)
      // 重连失败后，管理器会自动进行重试
    }
  },

  // 确保 WebSocket 连接（简化版，后端会自动订阅房间）
  async ensureWebSocketConnection() {
    const manager = this.getWebSocketManager()
    
    // 检查是否已登录
    if (!this.globalData.isLoggedIn || !this.globalData.userInfo) {
      console.log('用户未登录，跳过 WebSocket 连接')
      return
    }
    
    // 确保连接建立（连接成功后会自动发送 connect 消息，后端会自动订阅）
    try {
      if (!manager.isConnected()) {
        console.log('WebSocket 未连接，等待连接建立...')
        try {
          await manager.ensureConnection()
          console.log('WebSocket 连接已建立，检查 connect 消息发送状态...')
          
          // 等待连接建立后，确保已发送 connect 消息
          // 使用轮询检查，最多等待5秒
          let checkCount = 0
          const maxChecks = 10
          while (checkCount < maxChecks && manager.isConnected() && !manager.connectMessageSent) {
            await new Promise(resolve => setTimeout(resolve, 500))
            const sent = manager.ensureConnectMessageSent()
            if (sent) {
              console.log('✅ connect 消息已发送（ensureWebSocketConnection）')
              break
            }
            checkCount++
          }
          
          if (checkCount >= maxChecks && !manager.connectMessageSent) {
            console.warn('⚠️ 警告：连接已建立，但5秒后仍未发送 connect 消息')
          }
        } catch (err) {
          console.error('等待连接失败:', err)
          throw err
        }
      } else {
        // 连接已建立，确保已发送 connect 消息（重要：后端需要这个才能注册用户）
        console.log('WebSocket 已连接，检查 connect 消息发送状态...')
        const sent = manager.ensureConnectMessageSent()
        if (!sent) {
          console.warn('⚠️ 连接已建立但 connect 消息发送失败，将在后续重试')
        }
      }
      
      // 注册消息处理器（后端已自动订阅）
      await this.registerRoomMessageHandlers()
    } catch (error) {
      console.error('确保 WebSocket 连接失败:', error)
    }
  },

  // 注册房间消息处理器（后端会自动订阅，前端只需注册处理器）
  async registerRoomMessageHandlers() {
    const manager = this.getWebSocketManager()
    
    // 注册全局房间消息处理器（用于分发消息）
    if (!this._globalRoomMessageHandler) {
      this._globalRoomMessageHandler = (message) => {
        this.handleGlobalRoomMessage(message)
      }
    }
    
    // 如果知道当前房间，注册处理器（后端已自动订阅）
    const currentRoom = wx.getStorageSync('currentRoom') || this.globalData.currentRoom
    if (currentRoom && currentRoom.id) {
      manager.registerRoomHandler(currentRoom.id, this._globalRoomMessageHandler)
    }
  },

  // 刷新房间订阅（在创建/加入房间后调用，解决时序问题）
  // 这是一个高效的可复用函数，确保后端重新查询用户所在的房间
  refreshRoomSubscriptions() {
    const manager = this.getWebSocketManager()
    
    // 只有在连接已建立时才发送刷新消息
    if (!manager.isConnected()) {
      console.log('WebSocket未连接，跳过刷新房间订阅')
      return Promise.resolve()
    }

    const userId = wx.getStorageSync('userInfo')?.id || this.globalData.userInfo?.id
    if (!userId) {
      console.warn('无法获取用户ID，跳过刷新房间订阅')
      return Promise.resolve()
    }

    console.log('发送 refresh_rooms 消息，用户ID:', userId)
    manager.sendMessage('refresh_rooms', {
      user_id: userId
    })
    
    return Promise.resolve()
  },

  // 处理全局房间消息（分发给对应页面）
  handleGlobalRoomMessage(message) {
    console.log('收到全局房间消息:', message)
    
    const pages = getCurrentPages()
    const currentPage = pages[pages.length - 1]
    
    // 如果当前页面是房间页面，转发消息给它
    if (currentPage && currentPage.route === 'pages/room/room') {
      if (currentPage.handleWebSocketMessage) {
        currentPage.handleWebSocketMessage(message)
      }
    }
    
    // 也可以触发全局事件，让其他页面监听
    if (this.onRoomMessage) {
      this.onRoomMessage(message)
    }
  },

  // 获取WebSocket管理器单例
  getWebSocketManager() {
    return WebSocketManager.getInstance()
  },
  
  // 验证WebSocket单例（调试用）
  verifyWebSocketSingleton() {
    const manager1 = this.getWebSocketManager()
    const manager2 = WebSocketManager.getInstance()
    const stats = manager1.getConnectionStats()
    
    console.log('WebSocket单例验证:')
    console.log('- 实例相同:', manager1 === manager2)
    console.log('- 实例ID:', stats.instanceId)
    console.log('- 连接状态:', stats.connected)
    console.log('- 消息处理器数量:', stats.messageHandlersCount)
    console.log('- 房间订阅数量:', stats.roomSubscriptionsCount)
    
    return {
      isSingleton: manager1 === manager2,
      stats: stats
    }
  },
  
  // 检查网络配置
  checkNetworkConfiguration() {
    // 检查当前环境是否为体验版
    wx.getAccountInfoSync().miniProgram.envVersion
    const envVersion = __wxConfig.envVersion // 获取当前环境版本
    
    if (envVersion === 'trial') {
      console.log('当前为体验版小程序')
      // 可以在这里添加体验版特殊处理
    }
  },
  
  // 初始化全局错误处理器
  initGlobalErrorHandler() {
    // 监听未捕获的JavaScript异常
    wx.onError((error) => {
      console.error('全局错误捕获:', error);
      // 避免尝试访问不存在的日志文件
      if (error.includes('wxfile://usr/miniprogramLog/log2')) {
        console.warn('检测到日志文件访问错误，已忽略');
        return;
      }
    });
    
    // 监听页面加载失败
    wx.onPageNotFound((res) => {
      console.error('页面未找到:', res);
      wx.navigateTo({
        url: '/pages/index/index'
      });
    });
    
    // 监听网络状态变化
    wx.onNetworkStatusChange((res) => {
      if (!res.isConnected) {
        wx.showToast({
          title: '网络连接中断',
          icon: 'none'
        });
      }
    });
  },


  // 检查登录状态并初始化WebSocket（只有登录后才初始化）
  checkLoginStatusAndInitWebSocket() {
    const userInfo = wx.getStorageSync('userInfo')
    if (userInfo && userInfo.id) {
      console.log('用户已登录:', userInfo.nickname)
      this.globalData.userInfo = userInfo
      this.globalData.isLoggedIn = true
      // 用户已登录，初始化WebSocket
      this.initWebSocket()
    } else {
      console.log('用户未登录，等待登录后再初始化WebSocket')
      this.globalData.userInfo = null
      this.globalData.isLoggedIn = false
    }
  },

  // 检查登录状态（保留用于其他场景）
  checkLoginStatus() {
    const userInfo = wx.getStorageSync('userInfo')
    if (userInfo && userInfo.id) {
      this.globalData.userInfo = userInfo
      this.globalData.isLoggedIn = true
      console.log('用户已登录:', userInfo.nickname)
    } else {
      console.log('用户未登录')
      this.globalData.userInfo = null
      this.globalData.isLoggedIn = false
    }
  },

  // 设置登录状态
  setLoginStatus(userInfo) {
    this.globalData.userInfo = userInfo
    this.globalData.isLoggedIn = true
    wx.setStorageSync('userInfo', userInfo)
    console.log('登录成功:', userInfo.nickname)
    
    // 登录成功后，初始化WebSocket连接
    this.initWebSocket()
    
    // 登录成功后，确保 WebSocket 连接并订阅房间
    this.ensureWebSocketConnection().catch(err => {
      console.error('登录后初始化 WebSocket 失败:', err)
    })
  },

  // 检查是否正在授权流程中
  isInAuthFlow() {
    const pages = getCurrentPages()
    return pages.some(page => page.route === 'pages/auth/auth')
  },

  // 统一的授权状态检查
  checkAuthStatus() {
    return {
      isLoggedIn: this.globalData.isLoggedIn,
      hasUserInfo: !!this.globalData.userInfo,
      isInAuthFlow: this.isInAuthFlow()
    }
  },

  // 清除登录状态
  clearLoginStatus() {
    this.globalData.userInfo = null
    this.globalData.isLoggedIn = false
    wx.removeStorageSync('userInfo')
    console.log('已退出登录')
  },

  // 初始化WebSocket管理器
  initWebSocket() {
    console.log('初始化WebSocket管理器单例')
    // WebSocket管理器单例会在构造函数中自动初始化
    const manager = this.getWebSocketManager()
    console.log('WebSocket管理器已初始化:', manager.getStatus())
  },

  // WebSocket管理器代理方法
  registerMessageHandler(messageType, handler) {
    return this.getWebSocketManager().registerMessageHandler(messageType, handler)
  },

  unregisterMessageHandler(messageType, handler) {
    return this.getWebSocketManager().unregisterMessageHandler(messageType, handler)
  },

  subscribeRoom(roomId, handler) {
    return this.getWebSocketManager().subscribeRoom(roomId, handler)
  },

  unsubscribeRoom(roomId) {
    return this.getWebSocketManager().unsubscribeRoom(roomId)
  },

  sendWebSocketMessage(type, data) {
    return this.getWebSocketManager().sendMessage(type, data)
  },

  checkWebSocketConnection() {
    return this.getWebSocketManager().isConnected()
  },

  getWebSocketStatus() {
    return this.getWebSocketManager().getStatus()
  },

  forceReconnectWebSocket() {
    return this.getWebSocketManager().forceReconnect()
  },

  manualReconnectWebSocket() {
    const manager = this.getWebSocketManager()
    const status = manager.getStatus()
    
    if (status.connected) {
      console.log('WebSocket已连接，无需重连')
      return true
    }
    
    if (!status.canReconnect) {
      console.log('已达到最大重连次数，无法重连')
      return false
    }
    
    manager.forceReconnect()
    return true
  },



  // 发送WebSocket消息
  sendWebSocketMessage(action, data) {
    if (this.globalData.websocket) {
      wx.sendSocketMessage({
        data: JSON.stringify({
          action: action,
          data: data
        })
      })
    }
  },

  // 更新玩家列表
  updatePlayerList(user) {
    // 触发页面更新
    const pages = getCurrentPages()
    const currentPage = pages[pages.length - 1]
    if (currentPage && currentPage.updatePlayerList) {
      currentPage.updatePlayerList(user)
    }
  },

  // 移除玩家
  removePlayer(userId) {
    const pages = getCurrentPages()
    const currentPage = pages[pages.length - 1]
    if (currentPage && currentPage.removePlayer) {
      currentPage.removePlayer(userId)
    }
  },

  // 更新玩家分数
  updatePlayerScore(record) {
    const pages = getCurrentPages()
    const currentPage = pages[pages.length - 1]
    if (currentPage && currentPage.updatePlayerScore) {
      currentPage.updatePlayerScore(record)
    }
  },

  // 处理房间结算消息
  handleRoomSettlement(message) {
    const pages = getCurrentPages()
    const currentPage = pages[pages.length - 1]
    if (currentPage && currentPage.handleRoomSettlement) {
      currentPage.handleRoomSettlement(message)
    }
  },

  // 加入房间
  joinRoom(roomCode, userId) {
    this.sendWebSocketMessage('join_room', {
      room_code: roomCode,
      user_id: userId
    })
  },

  // 离开房间
  leaveRoom() {
    this.sendWebSocketMessage('leave_room', {})
  },

  // 添加分数
  addScore(targetUserId, score, description) {
    this.sendWebSocketMessage('add_score', {
      target_user_id: targetUserId,
      score: score,
      description: description
    })
  }
})